package com.kunpan.admin.common.utils.file;

import java.io.*;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Arrays;

import com.kunpan.admin.async.AsyncService;
import com.kunpan.admin.common.Enum.FileTypeEnum;
import com.kunpan.admin.config.KunPanConfig;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件类型工具类
 *
 * @author ruoyi
 */
public class FileUtils {

    private static final Logger log = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 获取文件类型
     * <p>
     * 例如: ruoyi.txt, 返回: txt
     *
     * @param file 文件名
     * @return 后缀（不含".")
     */
    public static String getFileType(File file) {
        if (null == file) {
            return StringUtils.EMPTY;
        }
        return getFileSuffix(file.getName());
    }

    /**
     * 获取文件类型
     * <p>
     * 例如: ruoyi.txt, 返回: txt
     *
     * @param fileName 文件名
     * @return 后缀（不含".")
     */
    public static String getFileSuffix(String fileName) {
        int separatorIndex = fileName.lastIndexOf(".");
        if (separatorIndex < 0) {
            return "";
        }
        return fileName.substring(separatorIndex + 1).toLowerCase();
    }

    /**
     * 获取链接中的文件名
     * <p>
     * 例如: test/text/ruoyi.txt, 返回: ruoyi.txt
     *
     * @param str 文件名
     * @return fileName
     */
    public static String getFileNameByURL(String str) {
        String[] arr = str.split("/");
        if (arr.length == 0) {
            return "";
        }
        return arr[arr.length-1];
    }

    public static String newFileName(String fileName) {
        int separatorIndex = fileName.lastIndexOf(".");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
        String heard = fileName.substring(0, separatorIndex);
        //使用stringBuilder拼接字符串
        StringBuilder stringBuilder = new StringBuilder();
        String name = stringBuilder.append(heard).append("_").append(dateFormat.format(System.currentTimeMillis())).
                append(".").append(getFileSuffix(fileName)).toString();
        return name;
    }

    /**
     * 根据文件后缀判断文件类型
     */
    public static int getMultipartFileType(String fileName) {
        String suffix = getFileSuffix(fileName);
        if (suffix != null) {
            for (int i = 0; i < MimeTypeUtils.DEFAULT_EXTENSION.length; i++) {
                String[] arr = MimeTypeUtils.DEFAULT_EXTENSION[i];
                if (Arrays.asList(arr).contains(suffix)) {//抓换为List集合，判断元素是否存在其中
                    //对应的后缀数组在二维数组中对应的索引就是枚举对应的文件类型
                    return i;
                }
            }
        }
        //都不存在，则返回其他类型
        return FileTypeEnum.OTHER.getValue();
    }


    /**
     * 上传
     */
    public static void fileUpload(MultipartFile multiFile, String fileName) throws IOException {
        String path = KunPanConfig.getUploadPath();
        File file = new File(path);
        if (!file.exists()) {
            boolean mkdirs = file.mkdirs();
            if (!mkdirs) {
                log.error("创建文件夹异常");
                throw new IOException("创建文件夹异常");
            }
        }
        try {
            //获取文件输入流
            InputStream inputStream = multiFile.getInputStream();
            //构建文件输出流
            String filePath = path + "/" + fileName;
            FileOutputStream outputStream = new FileOutputStream(filePath);
            int copy = FileCopyUtils.copy(inputStream, outputStream);
            //关闭流
            outputStream.close();
            inputStream.close();
            log.info("上传成功,文件大小：{}", copy);
        } catch (IOException e) {
            log.error("文件上传异常", e);
            throw new IOException(e.getMessage(), e);
        }
    }

    /**
     * 合并分片文件
     */
    public static Long mergeChunks(String fileMd5, Integer shardTotal, String filePath) throws IOException {
        File mergedFile = new File(filePath);
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(mergedFile, true))) {
            String path = KunPanConfig.getUploadPath() + "/" + fileMd5 + "chunk_";
            for (int i = 0; i < shardTotal; i++) {
                File chunkFile = new File(path + i);
                Files.copy(chunkFile.toPath(), bos);
                // 删除已合并的分片文件
                chunkFile.delete();
            }
            bos.flush();
        } catch (IOException e) {
            throw new IOException("报错", e);
        }
        // 返回合并后的文件大小
        return mergedFile.length();
    }
}